package scau.markmapscau.Control;

import javafx.embed.swing.SwingFXUtils;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import javafx.geometry.Rectangle2D;
import javafx.scene.SnapshotParameters;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.image.WritableImage;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Pane;
import scau.markmapscau.LaunchMain;
import scau.markmapscau.Model.Enum.ArrangeMode;
import scau.markmapscau.Model.Node.NodeArranger;
import scau.markmapscau.View.ViewerArranger;
import scau.markmapscau.Model.Node.Node;

import javax.imageio.ImageIO;

//controller调用写好的工具类,完成各项功能

public class Controller {
    public static double EXTRA = 500;
    public static double BEGIN_X_LEFT=200;
    public static double IMAGE_ADD_SIZE = 500;
    public static int INIT_FONT_SIZE = 15;

    @FXML
    private Pane StructZone;

    @FXML
    private ColorPicker ColorPick;
    @FXML
    private Button add;
    @FXML
    private Button delete;
    @FXML
    private AnchorPane MindMarkZone;

    @FXML
    private AnchorPane SmallPane;
    @FXML
    private ChoiceBox choiceStyleBox;
    @FXML
    private ColorPicker ColorPick2;

    @FXML
    private ScrollPane MindMapScrollPane;
    @FXML
    private Label scaleRateChange;

    void drawingNodesAndLines(){
        MindMarkZone.getChildren().clear();
        ViewerArranger viewerArranger= LaunchMain.viewerArranger;
        viewerArranger.nodeArranger.arrangeLayout();
        viewerArranger.drawNodes(viewerArranger.nodeArranger.getNodeList());
        viewerArranger.drawLines();
        viewerArranger.drawSmallPane();
    }

    @FXML
    void newNode(ActionEvent event) {//新建主题的时候,默认布局方式是右侧布局
        if(!checkForMutCenter()){return;}
        ViewerArranger viewerArranger= LaunchMain.viewerArranger;
        //新建节点,步骤:
        //1.首先新建节点,该节点为中心节点,为之设置各项数据
        //需要注意,这是前端,所以对Node的初始化只需要针对前端的显示需要来进行,其他的一概在后端处理
        Node node = new Node(0, NodeArranger.WIDTH,NodeArranger.HEIGHT,"#ffffff","FangSong");//TODO:改用计算节点高度的计算方法
        node.setNodeLocationX(BEGIN_X_LEFT);
        node.setNodeLocationY(MindMarkZone.getHeight()/2);
        node.setContent("中心节点");
        node.setSize(INIT_FONT_SIZE);
        //2.如果是中心节点,那么修改节点列表
        viewerArranger.nodeArranger.setParentNode(node);
        drawingNodesAndLines();
        //3.滑动滚动条,使之位于正中间
        MindMapScrollPane.setVvalue(0.45);
        MindMapScrollPane.setHvalue(0);
    }

    @FXML
    void newChildNode(ActionEvent event) {
        //首先检测是否有节点被选中
        ViewerArranger viewerArranger = LaunchMain.viewerArranger;
        if(!checkForEmptyList()){return;}
        if(!checkForChooseNode()){return ;}
        //System.out.println("点击了新建子节点事件:"+viewerArranger.selectNum);
        //否则的话就新建节点
        //1.新建节点,接口解释:这一步直接将子节点和父节点的连接起来了,而且高度宽度,放置位置都已经设置好了
        viewerArranger.newNodeByParent(viewerArranger.selectNum);
        //设置当前滑动框所需要的最小宽度
        //System.out.println(MindMapScrollPane.getPrefHeight()+" "+MindMapScrollPane.getPrefWidth());
        //2.直接画图
        drawingNodesAndLines();
        MindMarkZone.setPrefHeight(viewerArranger.nodeArranger.getMinHeight()+EXTRA);
        MindMarkZone.setPrefWidth(viewerArranger.nodeArranger.getMinWidth()+EXTRA);
    }

    @FXML
    void openFile(ActionEvent event){
        ViewerArranger viewerArranger = LaunchMain.viewerArranger;
        //返回从文件读到的哈希表信息
        viewerArranger.nodeArranger=viewerArranger.toolArranger.openFile();
        if(viewerArranger.nodeArranger == null){
            return ;
        }
        if(viewerArranger.nodeArranger.getNodeList() == null){
            return ;
        }
        if(viewerArranger.nodeArranger.getNodeList().size() == 0){
            return ;
        }
        viewerArranger.changTitle();
        //System.out.println(nodeList);
        //清除绘图区
//        MindMarkZone.getChildren().clear();
        //根据返回的信息哈希表，读取每个结点信息画框和结构树
        //viewerArranger.nodeArranger.setNodeList(nodeList);
        viewerArranger.nodeArranger.arrangeLayout();
        viewerArranger.drawNodes(viewerArranger.nodeArranger.getNodeList());
        //画线
//        arrangeMode  = ArrangeMode.RIGHT;
        viewerArranger.drawLines();
        viewerArranger.drawTree(viewerArranger.nodeArranger.getNodeList());
        String backColor = viewerArranger.nodeArranger.getBackColor();
        MindMarkZone.setStyle("-fx-background-color:"+backColor);
        MindMapScrollPane.setStyle("-fx-background-color: "+backColor);
        viewerArranger.drawSmallPane();
//        Color color = Color.decode(backColor);
//        Color color = System.Drawing.ColorTranslator.FromHtml(backColor);
        MindMapScrollPane.setVvalue(0.45);
        MindMapScrollPane.setHvalue(0);
        scaleRateChange.setText(String.valueOf((int)(viewerArranger.nodeArranger.getScale()*100)));
//        根据结点来读
//        for(int i=0;i< nodeList.size();i++) {
//            Node node = (Node)nodeList.get(i);
        //输出看看有没有读取成功每一个结点信息
//            System.out.println(nodeList);
//            viewerArranger.newNodeByParent(node.getId());
    }
//    }

    @FXML
    void saveFile(ActionEvent event){
        ViewerArranger viewerArranger = LaunchMain.viewerArranger;
        //需要获取一个保存的目标文件的绝对路径
        viewerArranger.toolArranger.saveFile(viewerArranger.nodeArranger);
        viewerArranger.changTitle();
    }


    @FXML
    void exportPicture(ActionEvent event) {
        //注意：在Tool类无法获得绘图区面板MindMarkZone,所以直接在这实现
        ViewerArranger viewerArranger = LaunchMain.viewerArranger;
        if(viewerArranger.nodeArranger.getNodeList().size() == 0){
            Alert alert = new Alert(Alert.AlertType.WARNING,"当前绘图区是空的！");
            alert.showAndWait();
            return ;
        }
        //获取返回文件
        File exportFileChooser = viewerArranger.toolArranger.exportPicture();
//        String exportFilePath = exportFileChooser.getAbsolutePath();
        //以快照snapshot的形式读取
        //缓存保存字节数组
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        //思路：1.先判断根节点（id=0）所在位置；2.判断该绘图的布局；3.根据布局左右(即id=0和id最大)两边各加一定的距离
        //要先确定图片的宽度，根据原有面板图片比例才能计算出高度
//        double widthLeft = viewerArranger.nodeArranger.getNodeList().get(0).getNodeLocationX()-IMAGE_ADD_SIZE;
//        //得到哈希表最后一个结点的Id
//        int listLastId = viewerArranger.nodeArranger.getNodeList().size();
//        double widthRight = viewerArranger.nodeArranger.getNodeList().get(listLastId).getNodeLocationX()+IMAGE_ADD_SIZE;
//        double mindZoneWidth = widthLeft+widthRight;
//        System.out.println(mindZoneWidth);
        //555自己好好看看区别吧555
        double[] boarder = viewerArranger.nodeArranger.getBoarder();
        double startX = boarder[0],startY = boarder[1];
        double width = boarder[2]-boarder[0]+100,height = boarder[3]-boarder[1]+100;
        WritableImage writableImage =new WritableImage((int)width,(int)height);
        SnapshotParameters parameters = new SnapshotParameters();
        Rectangle2D rectangle = new Rectangle2D(startX,startY,width,height);
        parameters.setViewport(rectangle);
        writableImage = MindMarkZone.snapshot(parameters,writableImage);
//        WritableImage writableImage =new WritableImage((int)MindMarkZone.getWidth(),(int)MindMarkZone.getHeight());
//        writableImage = MindMarkZone.snapshot(null,writableImage);
        if(exportFileChooser != null){
            try{
                ImageIO.write(SwingFXUtils.fromFXImage(writableImage,null),"PNG",byteArrayOutputStream);
                ImageIO.write(SwingFXUtils.fromFXImage(writableImage,null),"JPG",byteArrayOutputStream);
                FileOutputStream fileOutputStream = new FileOutputStream(exportFileChooser);
                fileOutputStream.write((byteArrayOutputStream.toByteArray()));
                fileOutputStream.close();
                byteArrayOutputStream.close();
                Alert saveSucInfo = new Alert(Alert.AlertType.INFORMATION,"导出成功！");
                saveSucInfo.setTitle("导出图片");
                saveSucInfo.showAndWait();
            }catch (IOException e){
                System.out.println("Couldn't Export As a Picture!");
            }
        }
    }

    @FXML
    void onChaneLayoutRight(ActionEvent event) {//重新布局,改为右侧布局
        if(!checkForEmptyList()){return;}
        ViewerArranger viewerArranger = LaunchMain.viewerArranger;
        viewerArranger.nodeArranger.setArrangeMode(ArrangeMode.RIGHT);
        viewerArranger.nodeArranger.arrangeLayout();//自动聚焦到父节点
        drawingNodesAndLines();
        MindMapScrollPane.setVvalue(0.55);
        MindMapScrollPane.setHvalue(0);
    }



    @FXML
    void onChaneLayoutLeft(ActionEvent event) {//改为左侧布局
        if(!checkForEmptyList()){return ;}
        ViewerArranger viewerArranger = LaunchMain.viewerArranger;
        viewerArranger.nodeArranger.setArrangeMode(ArrangeMode.LEFT);
        viewerArranger.nodeArranger.arrangeLayout();
        drawingNodesAndLines();
        MindMapScrollPane.setVvalue(0.55);
        MindMapScrollPane.setHvalue(0.9);
    }

    @FXML
    void onChaneLayoutAuto(ActionEvent event) {//改为自动布局
        if(!checkForEmptyList()){return ;}
        ViewerArranger viewerArranger = LaunchMain.viewerArranger;
        viewerArranger.nodeArranger.setArrangeMode(ArrangeMode.AUTO);
        viewerArranger.nodeArranger.arrangeLayout();
        drawingNodesAndLines();
        MindMapScrollPane.setVvalue(0.5);
        MindMapScrollPane.setHvalue(0.5);
    }

    @FXML
    void onDeleteNode(ActionEvent event) {//删除当前选中节点
        if(!checkForEmptyList()){return;}
        if(!checkForChooseNode()){return;}
        //删除选中时图标变色
        ImageView imageView=new ImageView(new Image("file:src/main/resources/scau/markmapscau/image/add.png"));
        imageView.setFitHeight(22);
        imageView.setFitWidth(22);
        add.setGraphic(imageView);
        ImageView imageView2=new ImageView(new Image("file:src/main/resources/scau/markmapscau/image/delete.png"));
        imageView2.setFitHeight(22);
        imageView2.setFitWidth(22);
        delete.setGraphic(imageView2);
        //画图
        ViewerArranger viewerArranger = LaunchMain.viewerArranger;
        viewerArranger.deleteNode();
        viewerArranger.nodeArranger.arrangeLayout();
        drawingNodesAndLines();
    }


    @FXML
    void onEnlargeMarkMapZone(){
        if(!checkForEmptyList()){return ;}
        ViewerArranger viewerArranger = LaunchMain.viewerArranger;
        int rate = Integer.parseInt(scaleRateChange.getText());
        rate = viewerArranger.setScale(rate,1);
        scaleRateChange.setText(String.valueOf(rate));
        boolean isMax = false;
        boolean isMin = false;
        if(rate == 200){
            isMax = true;
        }
        if(rate == 50){
            isMin = true;
        }
        viewerArranger.nodeArranger.enlargeFontSize(isMax,isMin);
        viewerArranger.nodeArranger.arrangeLayout();
        drawingNodesAndLines();
    }

    @FXML
    void onReduceMarkMapZone(){
        if(!checkForEmptyList()){return ;}
        ViewerArranger viewerArranger = LaunchMain.viewerArranger;
        int rate = Integer.parseInt(scaleRateChange.getText());
        rate = viewerArranger.setScale(rate,2);
        scaleRateChange.setText(String.valueOf(rate));
        boolean isMax = false;
        boolean isMin = false;
        if(rate == 200){
            isMax = true;
        }
        if(rate == 50){
            isMin = true;
        }
        viewerArranger.nodeArranger.reduceFontSize(isMax,isMin);
        viewerArranger.nodeArranger.arrangeLayout();
        drawingNodesAndLines();
    }

    void callAlertForEmptyList(){
        Alert alert = new Alert(Alert.AlertType.WARNING,"请先新建思维导图再操作！");
        alert.showAndWait();
    }

    boolean checkForEmptyList(){
        ViewerArranger viewerArranger = LaunchMain.viewerArranger;
        if(viewerArranger.nodeArranger.getNodeList() == null){
            callAlertForEmptyList();
            return false;
        }
        if(viewerArranger.nodeArranger.getNodeList().size() == 0){
            callAlertForEmptyList();
            return false;
        }
        return true;
    }

    void callAlertForMutCenter(){
        Alert alert = new Alert(Alert.AlertType.ERROR,"你不能创建多个中心节点!");
        alert.showAndWait();
    }

    boolean checkForMutCenter(){
        ViewerArranger viewerArranger  = LaunchMain.viewerArranger;
        if(viewerArranger.nodeArranger.getNodeList().size()!=0){//防止多次创建中心节点
            callAlertForMutCenter();
            return false;
        }
        return true;
    }

    void callAlertForNotChooseNode(){
        Alert alert = new Alert(Alert.AlertType.ERROR,"你没有选择任何节点!");
        alert.showAndWait();
    }

    boolean checkForChooseNode(){
        ViewerArranger viewerArranger = LaunchMain.viewerArranger;
        if(viewerArranger.selectNum == -1){
            callAlertForNotChooseNode();
            return false;
        }
        return true;
    }


}